package org.example.stream;

import java.util.Objects;
import java.util.function.Function;
import java.util.function.Supplier;

public class LazyBuilder<T> implements Supplier<T> {
    private T value;
    /**
     * 懒加载的构造函数
     */
    private Supplier<T> supplier;

    public LazyBuilder(Supplier<T> supplier) {
        this.supplier = supplier;
    }

    /**
     * 懒加载构造函数
     *
     * @param supplier
     * @param <T>
     * @return
     */
    public static <T> LazyBuilder<T> of(Supplier<T> supplier) {
        return new LazyBuilder<>(supplier);
    }

    @Override
    public T get() {
        if (Objects.nonNull(value)) {
            return value;
        }
        if (Objects.nonNull(supplier)) {
            value = supplier.get();
            return value;
        }
        return null;
    }

    public T getOrDefault(T defaultValue) {
        return Objects.nonNull(get()) ? value : defaultValue;
    }

    public <S extends Throwable> T getOrThrow(Supplier<S> supplier) throws S {
        if (Objects.nonNull(get())) {
            return value;
        }
        throw supplier.get();
    }

    /**
     * 转换
     * @param function
     * @return
     * @param <R>
     */
    public  <R> LazyBuilder<R> map(Function<T, R> function) {
        return new LazyBuilder<>(() -> function.apply(get()));
    }

    /**
     * 扁平转换
     * @param function
     * @return
     * @param <R>
     */
    public  <R> LazyBuilder<R> flatMap(Function<T, LazyBuilder<R>> function) {
        return new LazyBuilder<>(() -> function.apply(get()).get());
    }


}
